/*

############################################################

THIS RULE IS DELETED!
THIS RULE IS DELETED!
THIS RULE IS DELETED!

Replaced by text rule that uses byte_extract.  Yay, byte_extract!

I'm being lazy about deleting this.  This means I'm going to just go ahead and delete the thing,
without using massive conditional compile crap.  This thing's gone, and I've got things to do.


 * DOES NOT USE BUILT-IN DETECTION FUNCTION
 *
 * alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:"WEB-CLIENT Microsoft Windows Movie Maker project file heap buffer overflow attempt"; flowbits:isset,file.mswmm; flowbits:isset,file.msproducer; flow:to_client,established; flowbits:isset,file.oless.v3; flowbits:isset,file.oless.v4; content:"W|00|m|00|t|00|o|00|o|00|l|00|s|00|V|00|a|00|l|00|i|00|d|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1A 00|"; nocase; content:"P|00|r|00|o|00|d|00|u|00|c|00|e|00|r|00 2E 00|d|00|a|00|t|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1A 00|"; nocase; metadata:policy balanced-ips drop, policy security-ips drop, service http; reference:cve,2010-0265; reference:url,www.microsoft.com/technet/security/bulletin/MS10-016.mspx; classtype:attempted-user; sid:16472; rev:1;)
 * 
 * Use at your own risk.
 *
 * Copyright (C) 2005-2008 Sourcefire, Inc.
 * 
 * This file is autogenerated via rules2c, by Brian Caswell <bmc@sourcefire.com>
 */


#include "sf_snort_plugin_api.h"
#include "sf_snort_packet.h"

#include <string.h> // For memcmp()

//#define DEBUG
#ifdef DEBUG
#define DEBUG_SO(code) code
#else
#define DEBUG_SO(code)
#endif

#ifndef READ_LITTLE_64
#define READ_LITTLE_64(p) ((((uint64_t)*(p+7)) << 56) | (((uint64_t)*(p+6)) << 48) |  \
                           (((uint64_t)*(p+5)) << 40) | (((uint64_t)*(p+4)) << 32) |  \
                           (((uint64_t)*(p+3)) << 24) | (((uint64_t)*(p+2)) << 16) |  \
                           (((uint64_t)*(p+1)) << 8)  | (uint64_t)*p)
#endif

#ifndef READ_LITTLE_32
#define READ_LITTLE_32(p) (*((uint8_t *)(p) + 3) << 24) \
                        | (*((uint8_t *)(p) + 2) << 16) \
                        | (*((uint8_t *)(p) + 1) << 8)  \
                        | (*(p))
#endif

/* declare detection functions */
int rule16472eval(void *p);

#if 0
/* declare rule data structures */
/* flowbits:isset "file.mswmm"; */
static FlowBitsInfo rule16472flowbits0 =
{
    "file.mswmm",
    FLOWBIT_ISSET,
    0,
};

static RuleOption rule16472option0 =
{
    OPTION_TYPE_FLOWBIT,
    {
        &rule16472flowbits0
    }
};
/* flowbits:isset "file.msproducer"; */
static FlowBitsInfo rule16472flowbits1 =
{
    "file.msproducer",
    FLOWBIT_ISSET,
    0,
};

static RuleOption rule16472option1 =
{
    OPTION_TYPE_FLOWBIT,
    {
        &rule16472flowbits1
    }
};
/* flow:established, to_client; */
static FlowFlags rule16472flow2 = 
{
    FLOW_ESTABLISHED|FLOW_TO_CLIENT
};

static RuleOption rule16472option2 =
{
    OPTION_TYPE_FLOWFLAGS,
    {
        &rule16472flow2
    }
};
/* flowbits:isset "file.oless.v3"; */
static FlowBitsInfo rule16472flowbits3 =
{
    "file.oless.v3",
    FLOWBIT_ISSET,
    0,
};

static RuleOption rule16472option3 =
{
    OPTION_TYPE_FLOWBIT,
    {
        &rule16472flowbits3
    }
};
/* flowbits:isset "file.oless.v4"; */
static FlowBitsInfo rule16472flowbits4 =
{
    "file.oless.v4",
    FLOWBIT_ISSET,
    0,
};

static RuleOption rule16472option4 =
{
    OPTION_TYPE_FLOWBIT,
    {
        &rule16472flowbits4
    }
};

// content:"W|00|m|00|t|00|o|00|o|00|l|00|s|00|V|00|a|00|l|00|i|00|d|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1A 00|", depth 0, nocase, fast_pattern; 
static ContentInfo rule16472content5 = 
{
    (uint8_t *) "W|00|m|00|t|00|o|00|o|00|l|00|s|00|V|00|a|00|l|00|i|00|d|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1A 00|", /* pattern (now in snort content format) */
    0, /* depth */
    0, /* offset */
    CONTENT_NOCASE|CONTENT_BUF_NORMALIZED, /* flags */
    NULL, /* holder for boyer/moore PTR */
    NULL, /* more holder info - byteform */
    0, /* byteform length */
    0 /* increment length*/
};

static RuleOption rule16472option5 = 
{
    OPTION_TYPE_CONTENT,
    {
        &rule16472content5
    }
};
// content:"P|00|r|00|o|00|d|00|u|00|c|00|e|00|r|00|.|00|d|00|a|00|t|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1A 00|", depth 0, nocase; 
static ContentInfo rule16472content6 = 
{
    (uint8_t *) "P|00|r|00|o|00|d|00|u|00|c|00|e|00|r|00|.|00|d|00|a|00|t|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1A 00|", /* pattern (now in snort content format) */
    0, /* depth */
    0, /* offset */
    CONTENT_NOCASE|CONTENT_BUF_NORMALIZED, /* flags */
    NULL, /* holder for boyer/moore PTR */
    NULL, /* more holder info - byteform */
    0, /* byteform length */
    0 /* increment length*/
};

static RuleOption rule16472option6 = 
{
    OPTION_TYPE_CONTENT,
    {
        &rule16472content6
    }
};
#endif

// Randomized content match to disable this rule
static ContentInfo rule16472content7 =
{
    (uint8_t *) "trfhsfdgopfdgretu894q94t r89tjms4e98t7qw4je7e9r807aser789serjcq45<F7>97q435u34e9OAW7E89ZSEJC4E9057S4890TR7JA4RE89TJ", /* pattern (now in snort content format) */
    0, /* depth */
    0, /* offset */
    CONTENT_NOCASE|CONTENT_BUF_NORMALIZED|CONTENT_FAST_PATTERN, /* flags */
    NULL, /* holder for boyer/moore PTR */
    NULL, /* more holder info - byteform */
    0, /* byteform length */
    0 /* increment length*/
};

static RuleOption rule16472option7 =
{
    OPTION_TYPE_CONTENT,
    {
        &rule16472content7
    }
};



/* references for sid 16472 */
/* reference: cve "2010-0265"; */
static RuleReference rule16472ref1 = 
{
    "cve", /* type */
    "2010-0265" /* value */
};

/* reference: url "www.microsoft.com/technet/security/bulletin/MS10-016.mspx"; */
static RuleReference rule16472ref2 = 
{
    "url", /* type */
    "www.microsoft.com/technet/security/bulletin/MS10-016.mspx" /* value */
};

static RuleReference *rule16472refs[] =
{
    &rule16472ref1,
    &rule16472ref2,
    NULL
};
/* metadata for sid 16472 */
/* metadata:service http, policy balanced-ips drop, policy security-ips drop; */
#if 0
static RuleMetaData rule16472service1 = 
{
    "service http"
};


static RuleMetaData rule16472policy1 = 
{
    "policy balanced-ips drop"
};

static RuleMetaData rule16472policy2 = 
{
    "policy security-ips drop"
};
#endif

static RuleMetaData *rule16472metadata[] =
{
//    &rule16472service1,
//    &rule16472policy1,
//    &rule16472policy2,
    NULL
};

RuleOption *rule16472options[] =
{
    &rule16472option7,
//    &rule16472option0,
//    &rule16472option1,
//    &rule16472option2,
//    &rule16472option3,
//    &rule16472option4,
//    &rule16472option5,
//    &rule16472option6,
    NULL
};

Rule rule16472 = {
   /* rule header, akin to => tcp any any -> any any */
   {
       IPPROTO_TCP, /* proto */
       "$EXTERNAL_NET", /* SRCIP     */
       "$HTTP_PORTS", /* SRCPORT   */
   
       0, /* DIRECTION */
       "$HOME_NET", /* DSTIP     */
   
       "any", /* DSTPORT   */
   },
   /* metadata */
   { 
       3,  /* genid */
       16472, /* sigid */
       7, /* revision */
       "attempted-user", /* classification */
       0,  /* hardcoded priority XXX NOT PROVIDED BY GRAMMAR YET! */
       "DELETED WEB-CLIENT Microsoft Windows Movie Maker project file heap buffer overflow attempt",     /* message */
       rule16472refs /* ptr to references */
       ,rule16472metadata
   },
   rule16472options, /* ptr to rule options */
   &rule16472eval, /* DO NOT use the built in detection function */
   1 //0 /* am I initialized yet? */
};

// NOTE: return 1 if it fails to read a stream length
//              0 otherwise
uint8_t rule16472_get_stream_len(uint64_t *stream_len, uint16_t major_version, const uint8_t *cursor_normal, const uint8_t *end_of_payload)
{
    cursor_normal += 54;  // move the cursor to the beginning of DirectoryEntry structure then move to StreamSize field

    if (major_version == 3) {

        if (cursor_normal + 4 > end_of_payload)
           return 1;  
        *stream_len = (uint64_t)READ_LITTLE_32(cursor_normal);

    } else { // if (major_version == 4)

        if (cursor_normal + 8 > end_of_payload)
            return 1;
        *stream_len = READ_LITTLE_64(cursor_normal);

    }

    return 0;
}

/* detection functions */
int rule16472eval(void *p) {

   return RULE_NOMATCH;
#if 0
    const uint8_t *cursor_normal = 0;
    SFSnortPacket *sp = (SFSnortPacket *) p;

    const uint8_t *beg_of_payload, *end_of_payload;

    uint16_t major_version;
    uint64_t producer_stream_len = 0;
    uint64_t wmtoolsvalid_stream_len = 0;

    DEBUG_SO(printf("rule16472eval enter\n");)

    if(sp == NULL)
        return RULE_NOMATCH;

    if(sp->payload == NULL)
        return RULE_NOMATCH;
        
    if ((processFlowbits(p, rule16472options[0]->option_u.flowBit) <= 0)    // flowbits:isset "file.mswmm";  
        && (processFlowbits(p, rule16472options[1]->option_u.flowBit) <= 0)) // flowbits:isset "file.msproducer";
        return RULE_NOMATCH;

    DEBUG_SO(printf("rule16472eval found mswmm or msproducer flowbit\n");)
    
    // flow:established, to_client;
    if (checkFlow(p, rule16472options[2]->option_u.flowFlags) <= 0)
        return RULE_NOMATCH;
    
    if (processFlowbits(p, rule16472options[3]->option_u.flowBit) > 0)      // flowbits:isset "file.oless.v3";
        major_version = 3;
    else if (processFlowbits(p, rule16472options[4]->option_u.flowBit) > 0) // flowbits:isset "file.oless.v4";
        major_version = 4;
    else
        return RULE_NOMATCH;

    DEBUG_SO(printf("major_version %d\n", major_version);)
    if(getBuffer(sp, CONTENT_BUF_NORMALIZED, &beg_of_payload, &end_of_payload) <= 0)
      return RULE_NOMATCH;
         
    // content:"W|00|m|00|t|00|o|00|o|00|l|00|s|00|V|00|a|00|l|00|i|00|d|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1A 00|", depth 0, nocase, fast_pattern;
    if (contentMatch(p, rule16472options[5]->option_u.content, &cursor_normal) > 0)
    {
        if (rule16472_get_stream_len(&wmtoolsvalid_stream_len, major_version, cursor_normal, end_of_payload))
            return RULE_NOMATCH;

        DEBUG_SO(printf("wmtoolsvalid_stream_len %lld\n", wmtoolsvalid_stream_len);)

        // Lame specific threat action here.
        // We could do this using stored stream data but it's probably not worth it.
        switch(wmtoolsvalid_stream_len) {

           case 4432:

               // Do some sort of additional checking here to make sure we're in the PoC
               // The rule16472_get_stream_len() call above verifies we have at least 54 bytes of data
               if(memcmp(cursor_normal, "\x02\x01\x02\x00\x00\x00\x01\x00\x00\x00\xff\xff\xff\xff", 14) == 0) {
                  DEBUG_SO(printf("Alerting on shellcode poc\n");)
                  return RULE_MATCH;
               }

               break;

           case 65535:
               // Also a specific threat, but I'm not going to do additional verification for this
               DEBUG_SO(printf("Alerting on normal pocs\n");)
               return RULE_MATCH;
               break;

        }
    }
    else
        return RULE_NOMATCH;    

    // content:"P|00|r|00|o|00|d|00|u|00|c|00|e|00|r|00|.|00|d|00|a|00|t|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1A 00|", depth 0, nocase;
    if (contentMatch(p, rule16472options[6]->option_u.content, &cursor_normal) > 0)
    {
        if (rule16472_get_stream_len(&producer_stream_len, major_version, cursor_normal, end_of_payload))
            return RULE_NOMATCH;

        DEBUG_SO(printf("producer_stream_len %lld\n", producer_stream_len);)
    }
    else {
        DEBUG_SO(printf("rule16472eval did not find Producer.dat content match\n");)
        return RULE_NOMATCH;
    }

    DEBUG_SO(printf("rule16472eval wmtoolsvalid_stream_len = %d, producer_stream_len = %d\n", wmtoolsvalid_stream_len, producer_stream_len);)
            
    if (wmtoolsvalid_stream_len > producer_stream_len)
        return RULE_MATCH;          

    return RULE_NOMATCH;
#endif
}

/*
Rule *rules[] = {
    &rule16472,
    NULL
};
*/
